#ifndef AVALON_MOCKCLIENTCHANNEL_HPP
#define AVALON_MOCKCLIENTCHANNEL_HPP
#include "Avalon/IO/Channel.hpp"
#include "Avalon/IOTests/IOTests.hpp"

namespace Avalon {
namespace IO {
namespace Tests {
namespace Details {
  class ServerToClientChannel : public Channel {
    public:

      ServerToClientChannel(const boost::shared_ptr<Connection>& connection,
          const boost::shared_ptr<Reader>& reader,
          const boost::shared_ptr<Writer>& writer)
          : m_connection(connection),
            m_reader(reader),
            m_writer(writer) {}

      virtual ~ServerToClientChannel() {}

      Connection& GetConnection() {
        return *m_connection;
      }

      Reader& GetReader() {
        return *m_reader;
      }

      Writer& GetWriter() {
        return *m_writer;
      }

    private:
      boost::shared_ptr<Reader> m_reader;
      boost::shared_ptr<Writer> m_writer;
      boost::shared_ptr<Connection> m_connection;
  };
}

  /** \class MockClientChannel
   *  \brief Provides a Channel using mock components.
   */
  class MockClientChannel : public Channel {
    public:

      //! Constructs a MockClientChannel.
      /*!
        \param server The MockServerConnection to connect to.
      */
      MockClientChannel(MockServerConnection* server);

      virtual ~MockClientChannel();

      virtual Connection& GetConnection();

      virtual Reader& GetReader();

      virtual Writer& GetWriter();

    private:
      friend class MockClientConnection;
      boost::shared_ptr<MockClientConnection> m_connection;
      boost::shared_ptr<PipedReader> m_reader;
      boost::shared_ptr<PipedWriter> m_serverWriter;
      boost::shared_ptr<PipedReader> m_serverReader;
      boost::shared_ptr<PipedWriter> m_writer;

      Channel* CreateServerChannel();
  };
}
}
}

#endif // AVALON_MOCKCLIENTCHANNEL_HPP
